package com.jacky.数据结构;

import java.util.HashMap;
import java.util.Map;

public class LRUCache_146 {

    Node head, tail;
    //总容量
    int capacity;
    //当前使用的大小
    int size;
    Map<Integer, Node> cache;


    public LRUCache_146(int capacity) {
        this.capacity = capacity;
        // 初始化链表
        initLinkedList();
        size = 0;
        cache = new HashMap<>(capacity + 2);
    }

    /**
     * 根据节点的key值，获得节点的value值
     * @param key
     * @return
     */
    public int get(int key) {
        Node node = cache.get(key);
        //如果在map中找不到节点，返回-1
        if (node == null) {
            return -1;
        }
        // 节点存在就移动到头部，再返回要查询的节点的value值
        moveToHead(node);
        return node.value;
    }

    /**
     * 将节点加入到头结点，如果容量已满，将会删除尾结点
     *
     * @param key
     * @param value
     */
    public void put(int key, int value) {
        Node node = cache.get(key);
        if (node != null) {
            node.value = value;
            moveToHead(node);
            return;
        }
        //
        // 不存在，判断容量是否满了，如果容量已满 删除尾结点，再插入到头节点
        if (size == capacity) {
            //通过尾节点哨兵获得尾节点
            Node lastNode = tail.pre;
            //把尾节点从链表中移除
            deleteNode(lastNode);
            //把尾结点从map中移除
            cache.remove(lastNode.key);
            size--;
        }
        // 加入头结点

        Node newNode = new Node();
        newNode.key = key;
        newNode.value = value;
        addNode(newNode);
        cache.put(key, newNode);
        size++;

    }

    private void moveToHead(Node node) {
        // 首先删除原来节点的关系
        deleteNode(node);
        addNode(node);
    }

    private void addNode(Node node) {
        head.next.pre = node;
        node.next = head.next;

        node.pre = head;
        head.next = node;
    }

    private void deleteNode(Node node) {
        node.pre.next = node.next;
        node.next.pre = node.pre;
    }


    public static class Node {
        public Node pre;
        public Node next;
        public int key;
        public int value;

        public Node(int key, int value) {
            this.key = key;
            this.value = value;
        }

        public Node() {
        }
    }

    private void initLinkedList() {
        head = new Node();
        tail = new Node();

        head.next = tail;
        tail.pre = head;

    }

    public static void main(String[] args) {

        LRUCache_146 cache = new LRUCache_146(2);

        cache.put(1, 1);
        cache.put(2, 2);
        System.out.println(cache.get(1));
        cache.put(3, 3);
        System.out.println(cache.get(2));
        System.out.println(cache.get(3));

        System.out.println('a'=='a');

    }
}